package com.hatch.utils
{
	import com.hatch.events.DataObjectEvent;	

	import flash.events.EventDispatcher;
	import flash.media.Sound;
	import flash.media.SoundChannel;
	import flash.media.SoundTransform;
	import flash.net.URLRequest;
	import flash.utils.getDefinitionByName;

	import gs.TweenLite;

	public class SoundManager extends EventDispatcher
	{
		private static var _instance:SoundManager;
		public static var value:String;
		private var _muted:Boolean = false;
		private static var eventChannel:SoundChannel;
		private static var eventTransform:SoundTransform;
		private static var eventVolume:Number;
		private static var ambientChannel:SoundChannel;
		private static var ambientTransform:SoundTransform;
		private static var ambientVolume:Number;

		public function SoundManager(enforcer:SingletonEnforcer)
		{
		}

		public static function getInstance():SoundManager 
		{
			if( SoundManager._instance == null )
			{
				SoundManager._instance = new SoundManager(new SingletonEnforcer());
			}
			return SoundManager._instance;
		}

		public function get muted():Boolean
		{ 
			return _muted; 
		}

		public function play(name:String, vol:Number = 1, loop:Boolean = false):void
		{
			if(_muted) return;
			
			try
			{
				var soundItem:Class = getDefinitionByName(name) as Class;
				var snd:* = new soundItem();
				eventChannel = snd.play(0, loop ? int.MAX_VALUE : 0);
			
				if(eventChannel != null)
				{	
					eventTransform = new SoundTransform(vol);
					eventChannel.soundTransform = eventTransform;
				}
			}
			catch(e:Error)
			{
				trace(e);	
			}
		}

		public function playURL(url:String, vol:Number = 1, loop:Boolean = false):void
		{
			trace("SoundManager::playURL() " + url);
			if(_muted) return;
			
			var snd:Sound = new Sound(new URLRequest(url));			
			eventChannel = snd.play(0, loop ? int.MAX_VALUE : 0);
			
			if(eventChannel != null)
			{	
				eventTransform = new SoundTransform(vol);
				eventChannel.soundTransform = eventTransform;
			}
		}

		public function playAmbient(url:String, vol:Number = 1):void 
		{
			if(_muted) return;
			var snd:Sound = new Sound(new URLRequest(url));
			ambientChannel = snd.play(0, int.MAX_VALUE);
			ambientVolume = vol;
			if(ambientChannel != null)
			{	
				ambientTransform = new SoundTransform(ambientVolume);
				ambientChannel.soundTransform = ambientTransform;
			}
		}

		public function toggleMute():void 
		{			
			_muted = !_muted;
			trace("SoundManager::toggleMute() " + _muted + " ambientChannel: " + ambientChannel);
			dispatchEvent(new DataObjectEvent("muteupdate", { eventType: "muteupdate", mute_status: _muted }));
			var vol:Number;
			if (ambientChannel != null)
			{
				vol = _muted ? 0 : ambientVolume;
				TweenLite.to(ambientTransform, 0.5, { volume: vol, onUpdate: onUpdateVolume, onUpdateParams: [ambientChannel, ambientTransform] });
			}
			
			if (eventChannel != null)
			{
				vol = _muted ? 0 : eventVolume;
				TweenLite.to(eventTransform, 0.5, { volume: vol, onUpdate: onUpdateVolume, onUpdateParams: [eventChannel, eventTransform] });
			}			
		}

		private function onUpdateVolume(channel:SoundChannel, transform:SoundTransform):void 
		{			
			channel.soundTransform = transform;
		}

		public function stopUrl():void 
		{			
			TweenLite.to(eventTransform, 0.5, { volume: 0, onUpdate: onUpdateVolume, onUpdateParams: [eventChannel, eventTransform] });
		} 
	}//end SoundManager
}

//singleton enforcer

class SingletonEnforcer
{
}